package com.orangelife.utils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * 拼音转换成首字母大写字符串
 * 
 * @author kangpk
 * 
 */
public class CnToSpell {

	private static Map<String, List<String>> pinyinMap = new HashMap<String, List<String>>();

	public static void main(String[] args) {
		String str = "厦门三区";
		// String str = "龙港巷店";

		String py = getPingYin(str);
		System.out.println(str + " = " + py);

		String jp = getPinYinHeadChar(str);
		System.out.println(str + " = " + jp);
	}

	/**
	 * 将某个字符串的首字母 大写
	 * 
	 * @param str
	 * @return
	 */
	public static String convertInitialToUpperCase(String str) {
		if (str == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		char[] arr = str.toCharArray();
		for (int i = 0; i < arr.length; i++) {
			char ch = arr[i];
			if (i == 0) {
				sb.append(String.valueOf(ch).toUpperCase());
			} else {
				sb.append(ch);
			}
		}

		return sb.toString();
	}

	/**
	 * 只取某个字符串的首字母 大写
	 * 
	 * @param str
	 * @return
	 */
	public static String convertInitialToUpperCases(String str) {
		if (str == null) {
			return null;
		}
		StringBuffer sb = new StringBuffer();
		char[] arr = str.toCharArray();
		for (int i = 0; i < arr.length; i++) {
			char ch = arr[i];
			if (i == 0) {
				sb.append(String.valueOf(ch).toUpperCase());
			}
		}

		return sb.toString();
	}

	/**
	 * 将汉字转换为全拼
	 * 
	 * @param src
	 * @return
	 */
	public static String getPingYin(String chinese) {
		initPinyin("duoyinzi_dic.txt");
		StringBuffer pinyin = new StringBuffer();

		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

		char[] arr = chinese.toCharArray();

		for (int i = 0; i < arr.length; i++) {

			char ch = arr[i];

			if (ch > 128) { // 非ASCII码
				// 取得当前汉字的所有全拼
				try {

					String[] results = PinyinHelper.toHanyuPinyinStringArray(
							ch, defaultFormat);

					if (results == null) { // 非中文

						return "";
					} else {

						int len = results.length;

						if (len == 1) { // 不是多音字

							String py = results[0];
							if (py.contains("u:")) { // 过滤 u:
								py = py.replace("u:", "v");
								System.out.println("filter u:" + py);
							}
							pinyin.append(py);
							/*
							 * pinyin.append(convertInitialToUpperCase(results[0]
							 * ));
							 */

						} else if (results[0].equals(results[1])) { // 非多音字
																	// 有多个音，取第一个

							pinyin.append(results[0]);
							/*
							 * pinyin.append(convertInitialToUpperCase(results[0]
							 * ));
							 */

						} else { // 多音字

							System.out.println("多音字：" + ch);

							int length = chinese.length();

							boolean flag = false;

							String s = null;

							List<String> keyList = null;

							for (int x = 0; x < len; x++) {

								String py = results[x];

								if (py.contains("u:")) { // 过滤 u:
									py = py.replace("u:", "v");
									System.out.println("filter u:" + py);
								}

								keyList = pinyinMap.get(py);

								if (i + 3 <= length) { // 后向匹配2个汉字 大西洋
									s = chinese.substring(i, i + 3);
									if (keyList != null
											&& (keyList.contains(s))) {
										System.out.println("last 2 > " + py);
										pinyin.append(py);
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (results[0]));
										 */
										flag = true;
										break;
									}
								}
								if (i + 2 <= length) { // 后向匹配 1个汉字 大西
									s = chinese.substring(i, i + 2);
									if (keyList != null
											&& (keyList.contains(s))) {
										System.out.println("last 1 > " + py);
										pinyin.append(py);
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (results[0]));
										 */
										flag = true;
										break;
									}
								}

								if ((i - 2 >= 0) && (i + 1 <= length)) { // 前向匹配2个汉字
																			// 龙固大
									s = chinese.substring(i - 2, i + 1);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before 2 < " + py);
										pinyin.append(py);
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (results[0]));
										 */
										flag = true;
										break;
									}
								}

								if ((i - 1 >= 0) && (i + 1 <= length)) { // 前向匹配1个汉字
																			// 固大
									s = chinese.substring(i - 1, i + 1);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before 1 < " + py);
										pinyin.append(py);
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (results[0]));
										 */
										flag = true;
										break;
									}
								}

								if ((i - 1 >= 0) && (i + 2 <= length)) { // 前向1个，后向1个
																			// 固大西
									s = chinese.substring(i - 1, i + 2);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before last 1 <> "
												+ py);
										pinyin.append(py);
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (results[0]));
										 */
										flag = true;
										break;
									}
								}
							}

							if (!flag) { // 都没有找到，匹配默认的 读音 大

								s = String.valueOf(ch);

								for (int x = 0; x < len; x++) {

									String py = results[x];

									if (py.contains("u:")) { // 过滤 u:
										py = py.replace("u:", "v");
										System.out.println("filter u:");
									}
									keyList = pinyinMap.get(py);

									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("default = " + py);
										pinyin.append(py); // 如果不需要拼音首字母大写
															// ，直接返回即可
										/*
										 * pinyin.append(convertInitialToUpperCase
										 * (py));//拼音首字母 大写
										 */
										break;
									}
								}
							}
						}
					}

				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyin.append(arr[i]);
			}
		}
		return pinyin.toString();
	}

	/**
	 * 返回首字母大写字符串
	 * 
	 * @param str
	 * @return
	 */
	public static String getPinYinHeadChar(String chinese) {
		initPinyin("duoyinzi_dic.txt");
		StringBuffer pinyin = new StringBuffer();

		HanyuPinyinOutputFormat defaultFormat = new HanyuPinyinOutputFormat();
		defaultFormat.setCaseType(HanyuPinyinCaseType.LOWERCASE);
		defaultFormat.setToneType(HanyuPinyinToneType.WITHOUT_TONE);

		char[] arr = chinese.toCharArray();

		for (int i = 0; i < arr.length; i++) {

			char ch = arr[i];

			if (ch > 128) { // 非ASCII码
				// 取得当前汉字的所有全拼
				try {

					String[] results = PinyinHelper.toHanyuPinyinStringArray(
							ch, defaultFormat);

					if (results == null) { // 非中文

						return "";
					} else {

						int len = results.length;

						if (len == 1) { // 不是多音字

							// pinyin.append(results[0]);
							String py = results[0];
							if (py.contains("u:")) { // 过滤 u:
								py = py.replace("u:", "v");
								System.out.println("filter u:" + py);
							}
							pinyin.append(convertInitialToUpperCases(py));

						} else if (results[0].equals(results[1])) { // 非多音字
																	// 有多个音，取第一个

							// pinyin.append(results[0]);
							pinyin.append(convertInitialToUpperCases(results[0]));

						} else { // 多音字

							System.out.println("多音字：" + ch);

							int length = chinese.length();

							boolean flag = false;

							String s = null;

							List<String> keyList = null;

							for (int x = 0; x < len; x++) {

								String py = results[x];

								if (py.contains("u:")) { // 过滤 u:
									py = py.replace("u:", "v");
									System.out.println("filter u:" + py);
								}

								keyList = pinyinMap.get(py);

								if (i + 3 <= length) { // 后向匹配2个汉字 大西洋
									s = chinese.substring(i, i + 3);
									if (keyList != null
											&& (keyList.contains(s))) {
										// if (value != null &&
										// value.contains(s)) {

										System.out.println("last 2 > " + py);
										// pinyin.append(results[x]);
										pinyin.append(convertInitialToUpperCases(py));
										flag = true;
										break;
									}
								}

								if (i + 2 <= length) { // 后向匹配 1个汉字 大西
									s = chinese.substring(i, i + 2);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("last 1 > " + py);
										// pinyin.append(results[x]);
										pinyin.append(convertInitialToUpperCases(py));
										flag = true;
										break;
									}
								}

								if ((i - 2 >= 0) && (i + 1 <= length)) { // 前向匹配2个汉字
																			// 龙固大
									s = chinese.substring(i - 2, i + 1);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before 2 < " + py);
										// pinyin.append(results[x]);
										pinyin.append(convertInitialToUpperCases(py));
										flag = true;
										break;
									}
								}

								if ((i - 1 >= 0) && (i + 1 <= length)) { // 前向匹配1个汉字
																			// 固大
									s = chinese.substring(i - 1, i + 1);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before 1 < " + py);
										// pinyin.append(results[x]);
										pinyin.append(convertInitialToUpperCases(py));
										flag = true;
										break;
									}
								}

								if ((i - 1 >= 0) && (i + 2 <= length)) { // 前向1个，后向1个
																			// 固大西
									s = chinese.substring(i - 1, i + 2);
									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("before last 1 <> "
												+ py);
										// pinyin.append(results[x]);
										pinyin.append(convertInitialToUpperCases(py));
										flag = true;
										break;
									}
								}
							}

							if (!flag) { // 都没有找到，匹配默认的 读音 大

								s = String.valueOf(ch);

								for (int x = 0; x < len; x++) {

									String py = results[x];

									if (py.contains("u:")) { // 过滤 u:
										py = py.replace("u:", "v");
										System.out.println("filter u:");
									}

									keyList = pinyinMap.get(py);

									if (keyList != null
											&& (keyList.contains(s))) {

										System.out.println("default = " + py);
										// pinyin.append(results[x]);
										// //如果不需要拼音首字母大写 ，直接返回即可
										pinyin.append(convertInitialToUpperCases(py));// 拼音首字母
																						// 大写
										break;
									}
								}
							}
						}
					}

				} catch (BadHanyuPinyinOutputFormatCombination e) {
					e.printStackTrace();
				}
			} else {
				pinyin.append(arr[i]);
			}
		}
		return pinyin.toString();
	}

	/**
	 * 初始化 所有的多音字词组
	 * 
	 * @param fileName
	 */
	public static void initPinyin(String fileName) {
		BufferedReader br = null;

		String s = null;
		try {
			// 读取多音字的全部拼音表;
			InputStreamReader file = new InputStreamReader(
					CnToSpell.class.getResourceAsStream(fileName), "UTF-8");

			br = new BufferedReader(file);
			while ((s = br.readLine()) != null) {

				if (s != null) {
					String[] arr = s.split("#");
					String pinyin = arr[0];
					String chinese = arr[1];

					if (chinese != null) {
						String[] strs = chinese.split(" ");
						List<String> list = Arrays.asList(strs);
						pinyinMap.put(pinyin, list);
					}
				}
			}

		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				br.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * 将汉字转换为全拼
	 * 
	 * @param src
	 * @return
	 */
	/*
	 * public static String getPingYin(String src) {
	 * 
	 * char[] t1 = null; t1 = src.toCharArray(); String[] t2 = new
	 * String[t1.length]; HanyuPinyinOutputFormat t3 = new
	 * HanyuPinyinOutputFormat(); t3.setCaseType(HanyuPinyinCaseType.LOWERCASE);
	 * t3.setToneType(HanyuPinyinToneType.WITHOUT_TONE);
	 * t3.setVCharType(HanyuPinyinVCharType.WITH_V); String t4 = ""; int t0 =
	 * t1.length; try { for (int i = 0; i < t0; i++) { // 判断是否为汉字字符 if
	 * (java.lang.Character.toString(t1[i]).matches( "[\\u4E00-\\u9FA5]+")) { t2
	 * = PinyinHelper.toHanyuPinyinStringArray(t1[i], t3); t4 += t2[0]; } else
	 * t4 += java.lang.Character.toString(t1[i]); } // System.out.println(t4);
	 * return t4; } catch (BadHanyuPinyinOutputFormatCombination e1) {
	 * e1.printStackTrace(); } return t4; }
	 */

	/**
	 * 返回首字母大写字符串
	 * 
	 * @param str
	 * @return
	 */
	/*
	 * public static String getPinYinHeadChar(String str) { String temp = "";
	 * String demo = ""; String convert = ""; for (int j = 0; j < str.length();
	 * j++) { char word = str.charAt(j); String[] pinyinArray =
	 * PinyinHelper.toHanyuPinyinStringArray(word); if (pinyinArray != null) {
	 * convert += pinyinArray[0].charAt(0); } else { convert += word; } }
	 * for(int i=0;i<convert.length();i++){ if(convert.charAt(i)>='a' &&
	 * convert.charAt(i)<='z' || convert.charAt(i)>='A' &&
	 * convert.charAt(i)<='Z' || convert.charAt(i)>='0' &&
	 * convert.charAt(i)<='9'){ temp=convert.substring(i,i+1).toUpperCase();
	 * demo += temp; } } return demo; }
	 */

	// 将字符串转移为ASCII码
	public static String getCnASCII(String cnStr) {
		StringBuffer strBuf = new StringBuffer();
		byte[] bGBK;
		try {
			bGBK = cnStr.getBytes("UTF-8");

			for (int i = 0; i < bGBK.length; i++) {
				// System.out.println(Integer.toHexString(bGBK[i]&0xff));
				strBuf.append(Integer.toHexString(bGBK[i] & 0xff));
			}
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		return strBuf.toString();
	}

}
